package strings;

import common.MyLinkList;
import errors.MyWarning;

import java.util.LinkedList;
import java.util.List;

/**
 * User: MiF
 * Date: 29.12.11
 * Time: 16:51
 */
public class Str {
    private int line;
    private int shift;
    private String command;
    private String specComment;
    private String comment;

    private Str() {
        this.line = 0;
        this.shift = 0;
        this.command = "";
        this.specComment = "";
        this.comment = "";
    }

    public Str(int line, String string) {
        this.line = line;
        this.shift = getShift(string);
        string = string.trim();
        this.command = string;
        this.specComment = "";
        this.comment = "";
        MyLinkList<String> strs = split(this, string, "//", true, true, false);
        this.command = strs.get(0).trim();
        if (strs.size() > 1) {
            if (strs.get(1).startsWith("!")) {
                strs = split(this, strs.get(1).substring(1), "//", true, true, false);
                this.specComment = strs.get(0).trim();
            }
            if (strs.size() > 1)
                this.comment = strs.get(1).trim();
        }
    }

    public static Str getStaticStr(int line, String staticString) {
        Str str = new Str();
        str.line = line;
        str.command = staticString;
        return str;
    }

    public int getLine() {
        return line;
    }

    public int getShift() {
        return shift;
    }

    public String getCommand() {
        return command;
    }

    public String getSpecComment() {
        return specComment;
    }

    public String getComment() {
        return comment;
    }

    public void print() {
        System.out.printf("%s%s//!%s//%s  line:%d\n",getShift(shift), command, specComment, comment, line);
    }

    private static String getShift(int shift) {
        String t="";
        for(int i=0;i<shift;i++)
            t+=" ";
        return t;
    }

    private static int getShift(String str) {
        int i = 0;
        while (i < str.length() && str.charAt(i) == ' ')
            i++;
        return i;
    }

    public static MyLinkList<String> split(Str str, String string, String splitter, boolean firstOnly, boolean quotes, boolean blocks) {
        MyLinkList<String> strings = new MyLinkList<String>();

        String temp = "";
        boolean quot = false;
        int quotPos = -1;
        List<Integer> block = new LinkedList<Integer>();
        boolean backSlashBefore = false;
        boolean firstFind = false;

        for (int i = 0; i < string.length(); i++) {
            temp += string.charAt(i);
            if (quotes && !quot && (string.charAt(i) == '\'' || string.charAt(i) == '"')) {
                quot = true;
                quotPos = i;
            } else if (quotes && quot) {
                if (!backSlashBefore && string.charAt(i) == string.charAt(quotPos))
                    quot = false;
            } else if (blocks && (string.charAt(i) == '(' || string.charAt(i) == '[' || string.charAt(i) == '{')) {
                block.add(i);
            } else if (blocks && block.size() > 0) {
                char ch = string.charAt(block.get(block.size() - 1));
                if (ch == '(' && string.charAt(i) == ')' || ch == '[' && string.charAt(i) == ']' || ch == '{' && string.charAt(i) == '}')
                    block.remove(block.size() - 1);
            } else if ((!firstFind || firstFind && !firstOnly) && string.charAt(i) == splitter.charAt(0)) {
                int matchLen = 0;
                while (matchLen < splitter.length() && string.charAt(i + matchLen) == splitter.charAt(matchLen))
                    matchLen++;
                if (matchLen == splitter.length()) {
                    strings.add(temp.substring(0, temp.length() - 1));
                    temp = "";
                    i += splitter.length() - 1;
                    firstFind = true;
                }
            }

            backSlashBefore = string.charAt(i) == '\\' && !backSlashBefore;
        }
        if (quot)
            MyWarning.add(str, "У текстовой кавычки не найдена пара");
        if (quot)
            MyWarning.add(str, "У текстовой кавычки не найдена пара");
        strings.add(temp);
        return strings;
    }
}
